﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Collections;

namespace UndirectedGraphs
{
    public class Graph
    {
        private int _V;
        private int _E = 0;
        private Dictionary<int, List<int>> dictionary;


        private void Initialize()
        {
            dictionary = new Dictionary<int, List<int>>();

            for (int i = 0; i < _V; i++)
            {
                dictionary.Add(i, new List<int>());
            }        
        }
      
        // Create an empty graph with V vertices
        public Graph(int V)
        { 
            _V  = V;
            Initialize();
        }

        // Create a graph from an input stream
        public Graph(string inputFile)
        {
            int firstLine = 0;
            using (StreamReader reader = new StreamReader(inputFile))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    firstLine += 1;

                    if (firstLine == 1)
                    {
                        _V = Convert.ToInt32(line.Trim());
                        Initialize();
                    }
                    else if (firstLine == 2)
                    {
                        _E = Convert.ToInt32(line.Trim());
                    }
                    else
                    {
                        string[] words = line.Split(' ');
                        int _v = Convert.ToInt32(words[0]);
                        int _w = Convert.ToInt32(words[1]);
                        AddEdge(_v, _w);
                    }
                }
            }
        }

        // add an edge between v and w
        public void AddEdge(int v, int w)
        {
            dictionary[v].Add(w);
            dictionary[w].Add(v);

            _E += 1;
        }



        public List<int> adj(int v)
        {
            return dictionary[v];
        }


        // number of vertices
        public int V()
        {
            return _V;
        }

        // number of edges
        public int E()
        {
            return _E;
        }

        // string representation
        public String toString()
        {
            StringBuilder sb = new StringBuilder();
            

            sb.AppendLine(_V.ToString() + " vertices, " + _E.ToString() + " edges");
            for (int v = 0; v < _V; v++)
            {
                sb.Append(v.ToString() + ": ");
                foreach (int w in adj(v))
                {
                    sb.Append(w.ToString() + " ");
                }
                sb.Append(Environment.NewLine);
            }

            return sb.ToString();
        }

    }
}
